"""
后台任务管理器
用于管理批量操作的异步任务
"""
import threading
import time
import logging
from uuid import uuid4
from datetime import datetime
from typing import Dict, Any, List, Callable

# 使用标准 logging，避免在模块导入时需要 Flask app context
logger = logging.getLogger(__name__)


class TaskManager:
    """后台任务管理器"""
    
    def __init__(self):
        self.tasks: Dict[str, Dict[str, Any]] = {}
        self._lock = threading.Lock()
        # 自动清理已完成任务（24小时后）
        self._start_cleanup_thread()
    
    def create_task(self, task_type: str, total_items: int, metadata: Dict = None) -> str:
        """
        创建新任务
        
        Args:
            task_type: 任务类型（bulk_stop, bulk_restart等）
            total_items: 任务总数
            metadata: 附加元数据
        
        Returns:
            任务ID
        """
        task_id = str(uuid4())
        
        with self._lock:
            self.tasks[task_id] = {
                'task_id': task_id,
                'task_type': task_type,
                'status': 'running',  # running, completed, failed
                'progress': 0,
                'total': total_items,
                'current': 0,
                'results': [],
                'success_count': 0,
                'failed_count': 0,
                'start_time': datetime.now().isoformat(),
                'end_time': None,
                'error': None,
                'metadata': metadata or {}
            }
        
        logger.info(f"创建任务: {task_id} | 类型: {task_type} | 总数: {total_items}")
        return task_id
    
    def update_progress(self, task_id: str, current: int, result: Dict = None):
        """
        更新任务进度
        
        Args:
            task_id: 任务ID
            current: 当前完成数
            result: 单项任务结果
        """
        with self._lock:
            if task_id not in self.tasks:
                return
            
            task = self.tasks[task_id]
            task['current'] = current
            task['progress'] = int((current / task['total']) * 100) if task['total'] > 0 else 0
            
            if result:
                task['results'].append(result)
                if result.get('success'):
                    task['success_count'] += 1
                else:
                    task['failed_count'] += 1
    
    def complete_task(self, task_id: str, status: str = 'completed', error: str = None):
        """
        标记任务完成
        
        Args:
            task_id: 任务ID
            status: 完成状态（completed, failed）
            error: 错误信息
        """
        with self._lock:
            if task_id not in self.tasks:
                return
            
            task = self.tasks[task_id]
            task['status'] = status
            task['end_time'] = datetime.now().isoformat()
            task['progress'] = 100
            
            if error:
                task['error'] = error
            
            logger.info(f"任务完成: {task_id} | 状态: {status} | 成功: {task['success_count']} | 失败: {task['failed_count']}")
    
    def get_task(self, task_id: str) -> Dict[str, Any]:
        """获取任务详情"""
        with self._lock:
            return self.tasks.get(task_id, None)
    
    def get_all_tasks(self) -> List[Dict[str, Any]]:
        """获取所有任务"""
        with self._lock:
            return list(self.tasks.values())
    
    def cancel_task(self, task_id: str) -> bool:
        """
        取消任务
        
        Args:
            task_id: 任务ID
        
        Returns:
            是否成功取消
        """
        with self._lock:
            if task_id not in self.tasks:
                return False
            
            task = self.tasks[task_id]
            if task['status'] in ['completed', 'failed', 'cancelled']:
                return False
            
            task['status'] = 'cancelled'
            task['end_time'] = datetime.now().isoformat()
            logger.info(f"任务已取消: {task_id}")
            return True
    
    def is_task_cancelled(self, task_id: str) -> bool:
        """检查任务是否已被取消"""
        with self._lock:
            if task_id not in self.tasks:
                return False
            return self.tasks[task_id]['status'] == 'cancelled'
    
    def delete_task(self, task_id: str):
        """删除任务"""
        with self._lock:
            if task_id in self.tasks:
                del self.tasks[task_id]
                logger.info(f"删除任务: {task_id}")
    
    def _start_cleanup_thread(self):
        """启动清理线程"""
        def cleanup_old_tasks():
            while True:
                time.sleep(3600)  # 每小时检查一次
                
                with self._lock:
                    now = datetime.now()
                    task_ids_to_delete = []
                    
                    for task_id, task in self.tasks.items():
                        if task['status'] in ['completed', 'failed'] and task['end_time']:
                            end_time = datetime.fromisoformat(task['end_time'])
                            # 删除24小时前完成的任务
                            if (now - end_time).total_seconds() > 86400:
                                task_ids_to_delete.append(task_id)
                    
                    for task_id in task_ids_to_delete:
                        del self.tasks[task_id]
                    
                    if task_ids_to_delete:
                        logger.info(f"清理了 {len(task_ids_to_delete)} 个旧任务")
        
        thread = threading.Thread(target=cleanup_old_tasks, daemon=True)
        thread.start()


# 全局任务管理器实例
task_manager = TaskManager()

